package edu.hawaii.senin.iclouds.plotting;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import java.util.concurrent.Callable;

import org.jdom.Element;

/**
 * Encapsulates task for plotting routines.
 * 
 * @author Pavel Senin.
 * 
 */
public class FractionHLogParserTask implements Callable<String> {

  private String resE3FileName;
  private String resE4FileName;
  private String resE5FileName;
  private String resE6FileName;
  private String outFileName;

  private String populationType;
  private List<String> speciesOfInterest;

  /**
   * Empty constructor, does nothing.
   * 
   */

  public FractionHLogParserTask() {
    // does nothing;
  }

  /**
   * Instantiates the new task from JDOM Element provided.
   * 
   * @param e the element to parse task from.
   * @param speciesOfInterest the list of species of interest.
   */
  public FractionHLogParserTask(Element e, List<String> speciesOfInterest) {
    this.outFileName = e.getAttributeValue("output_file");
    this.populationType = e.getAttributeValue("population_type");
    this.resE3FileName = e.getChildText("logfile3e");
    this.resE4FileName = e.getChildText("logfile4e");
    this.resE5FileName = e.getChildText("logfile5e");
    this.resE6FileName = e.getChildText("logfile6e");

    this.speciesOfInterest = speciesOfInterest;
  }

  /**
   * Does the actual work.
   * 
   * @return the dummy debug string to be printed as the status on display.
   * @throws Exception if error encountered.
   */
  public String call() throws Exception {

    GeneralPopulationStorage LogSurfacePopulation3 = null;
    GeneralPopulationStorage LogSurfacePopulation4 = null;
    GeneralPopulationStorage LogSurfacePopulation5 = null;
    GeneralPopulationStorage LogSurfacePopulation6 = null;

    // parse configs
    if ("active".equalsIgnoreCase(this.populationType)) {
      GeneralLogParser logParser = new GeneralLogParser();
      logParser.parse(resE3FileName);
      LogSurfacePopulation3 = new GeneralPopulationStorage(logParser.getActivePopulation());
      logParser.parse(resE4FileName);
      LogSurfacePopulation4 = new GeneralPopulationStorage(logParser.getActivePopulation());
      logParser.parse(resE5FileName);
      LogSurfacePopulation5 = new GeneralPopulationStorage(logParser.getActivePopulation());
      logParser.parse(resE6FileName);
      LogSurfacePopulation6 = new GeneralPopulationStorage(logParser.getActivePopulation());
    }
    else if ("buried".equalsIgnoreCase(this.populationType)) {
      GeneralLogParser logParser = new GeneralLogParser();
      logParser.parse(resE3FileName);
      LogSurfacePopulation3 = new GeneralPopulationStorage(logParser.getBuriedPopulation());
      logParser.parse(resE4FileName);
      LogSurfacePopulation4 = new GeneralPopulationStorage(logParser.getBuriedPopulation());
      logParser.parse(resE5FileName);
      LogSurfacePopulation5 = new GeneralPopulationStorage(logParser.getBuriedPopulation());
      logParser.parse(resE6FileName);
      LogSurfacePopulation6 = new GeneralPopulationStorage(logParser.getBuriedPopulation());
    }
    else if ("total".equalsIgnoreCase(this.populationType)) {
      GeneralLogParser logParser = new GeneralLogParser();
      logParser.parse(resE3FileName);
      LogSurfacePopulation3 = new GeneralPopulationStorage(logParser.getTotalPopulation());
      logParser.parse(resE4FileName);
      LogSurfacePopulation4 = new GeneralPopulationStorage(logParser.getTotalPopulation());
      logParser.parse(resE5FileName);
      LogSurfacePopulation5 = new GeneralPopulationStorage(logParser.getTotalPopulation());
      logParser.parse(resE6FileName);
      LogSurfacePopulation6 = new GeneralPopulationStorage(logParser.getTotalPopulation());

    }

    BufferedWriter writer = new BufferedWriter(new FileWriter(new File(this.outFileName)));

    // calculating the total H amount

    Long totalH_E3 = 0L;
    Long totalH_E4 = 0L;
    Long totalH_E5 = 0L;
    Long totalH_E6 = 0L;
    for (String s : speciesOfInterest) {
      System.out.println(s);
      Integer factor = getHatoms(s);
      if (null != LogSurfacePopulation3.getAmount(s)) {
        totalH_E3 += LogSurfacePopulation3.getAmount(s) * factor;
      }
      if (null != LogSurfacePopulation4.getAmount(s)) {
        totalH_E4 += LogSurfacePopulation4.getAmount(s) * factor;
      }
      if (null != LogSurfacePopulation5.getAmount(s)) {
        totalH_E5 += LogSurfacePopulation5.getAmount(s) * factor;
      }
      if (null != LogSurfacePopulation6.getAmount(s)) {
        totalH_E6 += LogSurfacePopulation6.getAmount(s) * factor;
      }
    }

    for (String s : speciesOfInterest) {
      writer.write(s + ",");
      if (null != LogSurfacePopulation3.getAmount(s)) {
        writer
            .write(String.valueOf((LogSurfacePopulation3.getAmount(s).doubleValue() * getHatoms(s)
                .doubleValue())
                / totalH_E3.doubleValue())
                + ",");
      }
      else {
        writer.write("0.0,");
      }
      if (null != LogSurfacePopulation4.getAmount(s)) {
        writer
            .write(String.valueOf((LogSurfacePopulation4.getAmount(s).doubleValue() * getHatoms(s)
                .doubleValue())
                / totalH_E4.doubleValue())
                + ",");
      }
      else {
        writer.write("0.0,");
      }
      if (null != LogSurfacePopulation5.getAmount(s)) {
        writer
            .write(String.valueOf((LogSurfacePopulation5.getAmount(s).doubleValue() * getHatoms(s)
                .doubleValue())
                / totalH_E5.doubleValue())
                + ",");
      }
      else {
        writer.write("0.0,");
      }
      if (null != LogSurfacePopulation6.getAmount(s)) {
        writer
            .write(String.valueOf((LogSurfacePopulation6.getAmount(s).doubleValue() * getHatoms(s)
                .doubleValue())
                / totalH_E6.doubleValue())
                + "\n");
      }
      else {
        writer.write("0.0\n");
      }
    }

    writer.flush();
    writer.close();

    return "Dummy debug: " + this.outFileName + " done!";

  }

  /**
   * Reports the amount of hydrogen atoms within the specie.
   * 
   * @param s the specie name.
   * @return the amount of hydrogen atoms.
   */
  Integer getHatoms(String s) {
    Integer res = 0;
    // H2SO4
    Integer curPos = 0;
    while (curPos < s.length()) {
      if (Character.isLetter(s.charAt(curPos))) {
        String atomName = String.valueOf(s.charAt(curPos));
        if ("H".equalsIgnoreCase(atomName)) {
          if ((curPos < (s.length() - 1)) && (Character.isDigit(s.charAt(curPos + 1)))) {
            res += Integer.valueOf(s.substring(curPos + 1, curPos + 2));
            curPos += 2;
          }
          else {
            res += 1;
            curPos += 1;
          }
        }
        else {
          curPos += 1;
        }
      }
      else {
        curPos += 1;
      }
    }
    return res;
  }

}
